import 'package:args/args.dart' as args;
import 'package:simulator/typedef/constant.dart';
import 'package:simulator/typedef/simu_option.dart';
import 'package:simulator/utils/common.dart';

///qemu-system-arm -M vexpress-a9 -m 512M -kernel ./linux-4.14.212/arch/arm/boot/zImage -dtb  ./linux-4.14.212/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd disk.img
class Options {
  static final Options _instance = Options._internal();
  static const int _vmMax = 48;
  static const int _driverMax = 5;
  Options._internal();

  static Options getInstance() {
    return _instance;
  }

  static final List<Option> _vmConfigGroups = List.empty(growable: true);
  static final List<Option> _driveConfigGroups = List.empty(growable: true);
  static late final args.ArgResults optDict;

  static final args.ArgParser argParser = args.ArgParser()
    ..addFlag('help',
        abbr: 'h', help: 'display this help and exit', negatable: false)
    ..addFlag('version',
        abbr: 'v',
        help: 'display version information and exit',
        negatable: false)
    ..addOption('machine',
        help: '-machine [type=]name[,prop[=value][,...]]',
        allowed: [
          'accel'
        ],
        allowedHelp: {
          'accel': 'accel=accels1[:accels2[:...]]\nThis is used to enable an accelerator. Depending on the target'
              'architecture, kvm, xen, hvf, nvmm, whpx or tcg can be available.'
              ' By default, tcg is used. If there is more than one accelerator'
              'specified, the next one is used if the previous one fails to'
              'initialize',
        })
    ..addFlag('M',
        help: 'sgx-epc.0.memdev=@var{memid},sgx-epc.0.node=@var{numaid}',
        negatable: false)
    ..addFlag('cpu',
        abbr: 'c', help: 'select CPU (-cpu help for list)', negatable: false)
    ..addFlag('user-config',
        help: 'do not load default user-provided config files at startup',
        defaultsTo: true,
        negatable: true)
    ..addFlag('kernel',
        help: 'do not load default user-provided config files at startup',
        defaultsTo: true,
        negatable: true);

  void addOpts(Option opt, {bool isVm = true}) {
    if (isVm) {
      if (_vmConfigGroups.length > _vmMax) {
        abort('ran out of space in vmConfigGroups');
      }
      _vmConfigGroups.add(opt);
    } else {
      if (_driveConfigGroups.length > _driverMax) {
        abort('ran out of space in driveConfigGroups');
      }
      _driveConfigGroups.add(opt);
    }
  }

  void parserAndValidate(List<String> args) {
    try {
      optDict = argParser.parse(args);
      if (!optDict.wasParsed('kernel')) {
        // if (optDict.wasParsed('append')) {
        //   abort('-append only allowed with -kernel option');
        // }
        // if (optDict.wasParsed('initrd')) {
        //   abort('-initrd only allowed with -kernel option');
        // }
      }
      if (optDict.flag('user-config')) {}
    } catch (e) {
      abort(e.toString());
    }
  }

  void processEarlyOptions() {}
  void processHelpOptions() {}

  void version() {
    print("SIMU emulator version: $simuVersion");
    print(simuCopyright);
  }

  void help() {
    version();
    print("usage: %s [options] [disk_image]\n"
        "'disk_image' is a raw hard disk image for IDE hard disk 0\n");
    print(argParser.usage);
    print("During emulation, the following keys are useful:\n"
        "ctrl-alt-f      toggle full screen\n"
        "ctrl-alt-n      switch to virtual console 'n'\n"
        "ctrl-alt-g      toggle mouse and keyboard grab\n"
        "\n"
        "When using -nographic, press 'ctrl-a h' to get some help.\n"
        "\n");
  }

  void readConfigFile({bool isDef = true}) {}
}
